﻿using Microsoft.AspNetCore.DataProtection.KeyManagement;

namespace anydata.Models
{
    public class SafeDictionary<TKey, TValue> where TKey : notnull
    {
        private readonly int _delay = 100;
        private Dictionary<TKey, TValue> _dict;
        private readonly ReaderWriterLock _locked;
        public SafeDictionary()
        {
            _locked = new ReaderWriterLock();
            _dict = new Dictionary<TKey, TValue>();
        }
        public int Count
        {
            get { return _dict.Count; }
        }

        public TValue this[TKey key]
        {
            get { return GetValue(key); }
            set { SetValue(key, value); }
        }
        public TKey[] Keys()
        {
            _locked.AcquireReaderLock(_delay);
            var keys = _dict.Keys.ToArray();
            _locked.ReleaseReaderLock();
            return keys;
        }

        public bool ContainsKey(TKey key)
        {
            _locked.AcquireReaderLock(_delay);
            bool contanins = _dict.ContainsKey(key);
            _locked.ReleaseReaderLock();
            return contanins;
        }

        public TValue? GetValue(TKey key)
        {
            _locked.AcquireReaderLock(_delay);
            TValue? value = default;
            if (_dict.ContainsKey(key))
            {
                value = _dict[key];
            }
            _locked.ReleaseReaderLock();
            return value;
        }

        public void SetValue(TKey key, TValue value)
        {
            _locked.AcquireWriterLock(_delay);
            if (_dict.ContainsKey(key))
            {
                _dict[key] = value;
            }
            else
            {
                _dict.Add(key, value);
            }
            _locked.ReleaseWriterLock();
        }

        public void Delete(TKey key)
        {
            _locked.AcquireWriterLock(_delay);
            if (_dict.ContainsKey(key))
            {
                _dict.Remove(key);
            }
            _locked.ReleaseWriterLock();
        }
    }
}
